﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Marmat.Foundation;
using Marmat.FrameWork;
using DevExpress.XtraPrinting.Native;

namespace Marmat.Template.WinForm
{
    public partial class SelectionUserForm : Marmat.Forms.Form, Marmat.Foundation.ISelectionUserForm, IProvider
    {
        IUserManager userManager;
        IOrganization organization;
        private IUserEntity mouseItem;
        private IUserEntity topSelection;
        private List<IUserEntity> userCollection = new List<IUserEntity>();
        private Dictionary<IUserEntity, Rectangle> userRectangleCollection = new Dictionary<IUserEntity, Rectangle>();
        private Dictionary<IUserEntity, Rectangle> checkRectangleCollection = new Dictionary<IUserEntity, Rectangle>();

        public SelectionUserForm()
        {
            InitializeComponent();
        }

        public bool ShowDialog(List<IUserEntity> users)
        {
            userCollection = users;
            this.topSelection = new UserEntity { NickName = "全选" };
            this.userManager = SystemCommand.GetService<IUserManager>();
            this.organization = SystemCommand.GetService<IOrganization>();
            if (this.organization is not null)
            {
                splitContainer1.Panel1Collapsed = true;
                splitContainer2.Panel1Collapsed = false;
                var collection = organization.GetOrganization();
                buildTreeNode(this.treeView1.Nodes, collection.Where(x => string.IsNullOrEmpty(x.Parent)));
                if (this.treeView1.Nodes.Count > 0)
                {
                    this.treeView1.Nodes[0].Expand();
                }
                void buildTreeNode(Marmat.Forms.Skin.TreeNodeCollection nodes, IEnumerable<IOrganizationEntity> organizations)
                {
                    foreach (var item in organizations)
                    {
                        var node = nodes.Add(item.Id, item.Name);
                        node.Tag = item;
                        buildTreeNode(node.Nodes, collection.Where(x => x.Parent == item.Id));
                    }
                }
            }
            else if (this.userManager is not null)
            {
                splitContainer1.Panel1Collapsed = true;
                splitContainer2.Panel1Collapsed = true;
                var collection = this.userManager.GetUserCollection();
                this.listBox1.Items.Add(topSelection);
                foreach (var user in collection)
                {
                    this.listBox1.Items.Add(user);
                }
            }
            this.label1.Text = $"已选择：{this.userCollection.Count}人";
            DialogResult dialog = this.ShowDialog();
            return dialog == DialogResult.OK;
        }


        private void listBox1_DrawItem(object sender, DrawItemEventArgs e)
        {
            object item = this.listBox1.Items[e.Index];
            if (item is IUserEntity user)
            {
                userRectangleCollection[user] = e.Bounds;
                Image img = Properties.Resources.check_default;
                if (this.mouseItem is not null && user.UserID == this.mouseItem.UserID)
                {
                    img = Properties.Resources.check_focus;
                    using SolidBrush brush = new SolidBrush(Color.FromArgb(244, 248, 252));
                    e.Graphics.FillRectangle(brush, e.Bounds);
                }
                if (user == this.topSelection)
                {
                    var items = this.listBox1.Items.OfType<IUserEntity>().Where(x => x != this.topSelection).Select(x => x.UserID).ToArray();
                    var unionCollection = this.userCollection.Select(x => x.UserID).Intersect(items).ToArray();
                    if (items.Length == unionCollection.Length && items.Length > 0)
                        img = Properties.Resources.check_checked;
                    else if (unionCollection.Length > 0)
                        img = Properties.Resources.check_un;
                }
                else if (userCollection.Exists(x => x.UserID == user.UserID))
                    img = Properties.Resources.check_checked;
                int left = 6;
                Rectangle rect = new Rectangle(left + (e.Bounds.Height - Math.Max(img.Height, img.Width)) / 2, e.Bounds.Top + (e.Bounds.Height - Math.Max(img.Height, img.Width)) / 2, img.Width, img.Height);
                e.Graphics.DrawImage(img, rect);
                checkRectangleCollection[user] = rect;
                left = rect.Right + 6;
                rect = new Rectangle(left, e.Bounds.Top, e.Bounds.Width - left, e.Bounds.Height);
                TextRenderer.DrawText(e.Graphics, user.NickName ?? user.UserID, e.Font, rect, Color.Black, Color.Transparent, TextFormatFlags.Left | TextFormatFlags.VerticalCenter);
            }
        }

        private void listBox1_MouseMove(object sender, MouseEventArgs e)
        {
            var item = this.userRectangleCollection.FirstOrDefault(x => x.Value.Contains(e.Location)).Key;
            if (item != mouseItem)
            {
                this.mouseItem = item;
                this.listBox1.Invalidate();
            }
        }

        private void listBox1_MouseLeave(object sender, EventArgs e)
        {
            IUserEntity item = null;
            if (item != mouseItem)
            {
                this.mouseItem = item;
                this.listBox1.Invalidate();
            }
        }

        private void listBox1_MouseDown(object sender, MouseEventArgs e)
        {
            var item = this.checkRectangleCollection.FirstOrDefault(x => x.Value.Contains(e.Location)).Key;
            if (item == this.topSelection)
            {
                var items = this.listBox1.Items.OfType<IUserEntity>().Where(x => x != this.topSelection).ToList();
                var items_list = items.Select(x => x.UserID).ToArray();
                var unionCollection = this.userCollection.Select(x => x.UserID).Intersect(items_list).ToArray();
                if (unionCollection.Length == items_list.Length && items_list.Length > 0)
                    this.userCollection.Where(x => items_list.Contains(x.UserID)).ToList().ForEach(x => this.userCollection.Remove(x));
                else
                {
                    items.ForEach(x =>
                    {
                        if (x != this.topSelection && !this.userCollection.Exists(item => item.UserID == x.UserID))
                            this.userCollection.Add(x);
                    });
                }
                this.listBox1.Invalidate();
                return;
            }
            item = this.userRectangleCollection.FirstOrDefault(x => x.Value.Contains(e.Location)).Key;
            if (item is not null && item != this.topSelection)
            {
                if (userCollection.Exists(x => x.UserID == item.UserID))
                    userCollection.Where(x => x.UserID == item.UserID).ToList().ForEach(x => userCollection.Remove(x));
                else
                    userCollection.Add(item);
                this.listBox1.Invalidate();
                this.label1.Text = $"已选择：{this.userCollection.Count}人";
            }
        }

        private void treeView1_AfterSelect(object sender, Forms.Skin.TreeViewEventArgs e)
        {
            if (this.organization is not null && e.Node.Tag is IOrganizationEntity item)
            {
                var collection = this.organization.GetUsers(item.Id);
                this.listBox1.Items.Clear();
                this.listBox1.Items.Add(topSelection);
                foreach (var user in collection)
                {
                    this.listBox1.Items.Add(user);
                }
            }
        }

        private void treeView1_DrawNode(object sender, Forms.Skin.DrawTreeNodeEventArgs e)
        {
            Color backColor = Color.Transparent;
            switch (e.State)
            {
                case TreeNodeStates.Default:
                    break;
                case TreeNodeStates.Hot:
                    backColor = Color.FromArgb(230, 246, 255);
                    break;
                case TreeNodeStates.Selected:
                    backColor = Color.FromArgb(179, 224, 255);
                    break;
            }
            using SolidBrush brush = new SolidBrush(backColor);
            e.Graphics.FillRectangle(brush, new Rectangle(e.Bounds.X, e.Bounds.Y, this.treeView1.Width - e.Bounds.X - 1, e.Bounds.Height));
            TextRenderer.DrawText(e.Graphics, e.Node.Text, this.treeView1.Font, e.Bounds, e.Node.ForeColor, Color.Transparent, TextFormatFlags.Left | TextFormatFlags.VerticalCenter);
        }

        private void treeView1_MeasureNode(object sender, Forms.Skin.MeasureTreeNodeEventArgs e)
        {
            e.Size = new Size(this.Width - this.treeView1.Indent * e.Node.Index, 25);
        }
    }
}
